home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 145 / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin / tools / sharp / sxwork2.lzh / サンプル基礎編 / スクロール / SCROLL.C < prev    next >
Text File  |  1994-03-10  |  10KB  |  297 lines

  1. /******************************************************************************
  2.  *    scroll.c:    画面スクロール処理関数
  3.  ******************************************************************************
  4.  *    Workroom SX-68K Sample Program Copyright 1994 SHARP
  5.  *
  6.  *    機能説明:
  7.  *    スクロールバーに対する処理と、それに付随する画面スクロールに関する
  8.  *    関数が、このソースファイルには収められています。
  9.  */
  10. #include <sxgraph.h>        /* グラフ系マネージャを利用するときに必要 */
  11. #include <window.h>        /* ウィンドウマンを利用するときに必要    */
  12. #include <control.h>        /* コントロールマンを利用するときに必要    */
  13. #include "scroll.h"        /* このプログラム固有のヘッダファイル    */
  14.  
  15. /******************************************************************************
  16.  *    createScrollBar():    スクロールバーの作成
  17.  ******************************************************************************
  18.  *    引数:    ComVal *pcv    共通変数へのポインタ
  19.  *    戻り値:    BOOLEAN        = TRUE:  作成成功
  20.  *                = FALSE: 作成失敗(終了)
  21.  */
  22. BOOLEAN createScrollBar(ComVal *pcv)
  23. {
  24.     Rect rcH, rcV;
  25.  
  26.     /* スクロールバーの位置と大きさを計算する */
  27.     rcH = rcV = pcv->windowPtr->graph.rect;
  28.     rcH.d.top = rcH.d.bottom - SCRLBR_H;
  29.     rcH.d.right -= SCRLBR_H;
  30.     rcV.d.left = rcV.d.right - SCRLBR_H;
  31.     rcV.d.bottom -= SCRLBR_H;
  32.  
  33.     pcv->scrlBrHHdl = CMOpen(    /* 横スクロールバーを作成する    */
  34.         pcv->windowPtr,        /* ウィンドウポインタ        */
  35.         &rcH,            /* 描画する位置と大きさ        */
  36.         NONTITLE,        /* タイトルは意味がない        */
  37.         TRUE,            /* 描画許可フラグ        */
  38.         0,            /* コントロールの初期値        */
  39.         0,            /* コントロールの最小値        */
  40.         0,            /* 最大値は描画前に再設定する    */
  41.         CI_SCLBRWH << 4,    /* 横スクロールバーのリソースID×16 */
  42.         0);            /* ユーザーの初期値        */
  43.     if (pcv->scrlBrHHdl == NULL)
  44.         return FALSE;        /* 失敗したのでFALSEを返す    */
  45.  
  46.     pcv->scrlBrVHdl = CMOpen(    /* 縦スクロールバーを作成する    */
  47.         pcv->windowPtr,        /* ウィンドウポインタ        */
  48.         &rcV,            /* 描画する位置と大きさ        */
  49.         NONTITLE,        /* タイトルは意味がない        */
  50.         TRUE,            /* 描画許可フラグ        */
  51.         0,            /* コントロールの初期値        */
  52.         0,            /* コントロールの最小値        */
  53.         0,            /* 最大値は描画前に再設定する    */
  54.         CI_SCLBRWV << 4,    /* 縦スクロールバーのリソースID×16 */
  55.         0);            /* ユーザーの初期値        */
  56.     if (pcv->scrlBrVHdl == NULL)
  57.         return FALSE;        /* 失敗したのでFALSEを返す    */
  58.  
  59.     return TRUE;            /* 成功したのでTRUEを返す    */
  60. }
  61.  
  62. /******************************************************************************
  63.  *    checkScrollBar():    スクロールバーのチェック
  64.  ******************************************************************************
  65.  *    引数:    ComVal *pcv    共通変数へのポインタ
  66.  *    戻り値:    BOOLEAN        = TRUE:  スクロール中
  67.  *                = FALSE: スクロール終了
  68.  */
  69. BOOLEAN checkScrollBar(ComVal *pcv)
  70. {
  71.     int partCode;            /* コントロールのパートコード    */
  72.     int sig = 1;            /* スクロールの方向(1 / -1)    */
  73.     int offset[2];
  74.     int dir, term;
  75.     LPoint lpt;
  76.     Control **ctrlHdl;        /* コントロールハンドル        */
  77.  
  78.     /* カレントグラフは、すでに設定されている */
  79.  
  80.     offset[0] = pcv->dispX;
  81.     offset[1] = pcv->dispY;
  82.     lpt = GMGlobalToLocal(pcv->event.ev.where.x_y);
  83.     /* コントロールの上でマウスが押されたか? */
  84.     partCode = CMFind(lpt, pcv->windowPtr, &ctrlHdl);
  85.     switch (partCode) {
  86.     case C_INTHUMB:            /* スクロールボックス        */
  87.         CMCheck(ctrlHdl, lpt, NULL);
  88.         if (ctrlHdl == pcv->scrlBrHHdl)
  89.             offset[0] = CMValueGet(ctrlHdl);
  90.         else if (ctrlHdl == pcv->scrlBrVHdl)
  91.             offset[1] = CMValueGet(ctrlHdl);
  92.         break;
  93.     case C_INUP:            /* スクロールアップボタン    */
  94.         sig = -1;
  95.         /* この処理は下に続きます */
  96.     case C_INDOWN:            /* スクロールダウンボタン    */
  97.         /* SHIFTキーが押されてないか? */
  98.         if (!(pcv->event.ev.how & KS_SHIFT)) {
  99.             if (ctrlHdl == pcv->scrlBrHHdl)
  100.                 dir = SCL_H;
  101.             else if (ctrlHdl == pcv->scrlBrVHdl)
  102.                 dir = SCL_V;
  103.             else
  104.                 break;
  105.             offset[dir] += FONTSIZE * 6 * sig;
  106.             if (offset[dir] < 0)
  107.                 offset[dir] = 0;
  108.             else if (offset[dir] >  CMMaxGet(ctrlHdl))
  109.                 offset[dir] = CMMaxGet(ctrlHdl);
  110.             break;
  111.         }
  112.         /* この処理は下に続きます */
  113.     case C_INPGUP:            /* ページスクロールアップボタン    */
  114.         if (partCode == C_INPGUP)
  115.             sig = -1;
  116.         /* この処理は下に続きます */
  117.     case C_INPGDOWN:        /* ページスクロールダウンボタン    */
  118.         if (ctrlHdl == pcv->scrlBrHHdl) {
  119.             dir = SCL_H;
  120.             term = pcv->windowPtr->graph.rect.d.right;
  121.         } else if (ctrlHdl == pcv->scrlBrVHdl) {
  122.             dir = SCL_V;
  123.             term = pcv->windowPtr->graph.rect.d.bottom;
  124.         } else
  125.             break;
  126.         offset[dir] += (term - SCRLBR_H) * sig;
  127.         if (offset[dir] < 0)
  128.             offset[dir] = 0;
  129.         else if (offset[dir] >  CMMaxGet(ctrlHdl))
  130.             offset[dir] = CMMaxGet(ctrlHdl);
  131.         break;
  132.     default:
  133.         return FALSE;
  134.     }
  135.  
  136.     setScrollOffset(pcv, offset);
  137.     return TRUE;
  138. }
  139.  
  140. /******************************************************************************
  141.  *    setScrollOffset():    スクロールバーの値を設定し、スクロールを行う
  142.  ******************************************************************************
  143.  *    引数:    ComVal *pcv    共通変数へのポインタ
  144.  *        int *poffset    スクロールバーのオフセット値へのポインタ
  145.  *    戻り値:    BOOLEAN        = TRUE:  処理完了
  146.  *                = FALSE: 確保失敗
  147.  */
  148. BOOLEAN setScrollOffset(ComVal *pcv, int *poffset)
  149. {
  150.     int lastAP;
  151.     Point dpt;
  152.     Rect rc, drc, trc;
  153.     Region **rgnHdl;
  154.  
  155.     /* カレントグラフは、すでに設定されている */
  156.  
  157.     rc = pcv->windowPtr->graph.rect;
  158.     rc.d.right -= SCRLBR_H;
  159.     rc.d.bottom -= SCRLBR_H;
  160.     drc = rc;
  161.     dpt.p.x = pcv->dispX - poffset[0];
  162.     dpt.p.y = pcv->dispY - poffset[1];
  163.     GMSlideRect(&drc, dpt.x_y);
  164.     /* 現在とスクロール後の表示領域が重なるか? */
  165.     if (GMAndRect(&trc, &rc, &drc)) {
  166.         rgnHdl = GMNewRgn();    /* リージョンハンドルを確保する    */
  167.         if (rgnHdl == NULL) {
  168.             pcv->errorCode = 8; /* 確保できなかった        */
  169.             return FALSE;    /* 失敗したのでFALSEを返す    */
  170.         }
  171.         /* 描画するときのカラーが黒とライトグレーだけの場合、アクセス
  172.            ページを1ページのみにすると、描画やスクロールの速度が速く
  173.            なります */
  174.         lastAP = GMAPage(G_PAGE1);
  175.         GMScroll(&rc, dpt.x_y, rgnHdl);
  176.         GMAPage(lastAP);    /* アクセスページを元に戻す    */
  177.         /* グローバル座標系に変換する */
  178.         GMSlideRgn(rgnHdl, GMLocalToGlobal(0));
  179.         WMAddRgn(rgnHdl);    /* アップデートリージョンに追加する */
  180.         GMDisposeRgn(rgnHdl);    /* リージョンハンドルを解放する    */
  181.     } else {
  182.         /* グローバル座標系に変換する */
  183.         GMSlideRect(&rc, GMLocalToGlobal(0));
  184.         WMAddRect(&rc);        /* アップデートリージョンに追加する */
  185.     }
  186.     pcv->dispX = poffset[0];    /* 新しい値をワークに登録する    */
  187.     pcv->dispY = poffset[1];
  188.     setScrollBar(pcv);        /* スクロールバーを再描画する    */
  189.     return TRUE;            /* 処理が完了したのでTRUEを返す    */
  190. }
  191.  
  192. /******************************************************************************
  193.  *    setScrollBar():    スクロールバーの値の設定
  194.  ******************************************************************************
  195.  *    引数:    ComVal *pcv    共通変数へのポインタ
  196.  */
  197. void setScrollBar(ComVal *pcv)
  198. {
  199.     ScrlVal svH, svV;
  200.  
  201.     /* スクロールバーの現在値、最大値を算出する */
  202.     calcScrollBar(pcv, &svH, &svV);
  203.  
  204.     if (svH.val != pcv->scrlH.val || svH.max != pcv->scrlH.max
  205.      || svH.dMax != pcv->scrlH.dMax) { /* 値に変更があるか?    */
  206.         /* コントロール定義関数のデータを設定する */
  207.         CMDefDataSet(pcv->scrlBrHHdl, LONGWORD(1, svH.dMax));
  208.         CMMaxSet(pcv->scrlBrHHdl, svH.max);
  209.         CMValueSet(pcv->scrlBrHHdl, svH.val);
  210.         pcv->scrlH = svH;
  211.     }
  212.  
  213.     if (svV.val != pcv->scrlV.val || svV.max != pcv->scrlV.max
  214.      || svV.dMax != pcv->scrlV.dMax) { /* 値に変更があるか?    */
  215.         /* コントロール定義関数のデータを設定する */
  216.         CMDefDataSet(pcv->scrlBrVHdl, LONGWORD(1, svV.dMax));
  217.         CMMaxSet(pcv->scrlBrVHdl, svV.max);
  218.         CMValueSet(pcv->scrlBrVHdl, svV.val);
  219.         pcv->scrlV = svV;
  220.     }
  221. }
  222.  
  223. /******************************************************************************
  224.  *    calcScrollBar():    スクロールバーの現在値、最大値の算出
  225.  ******************************************************************************
  226.  *    引数:    ComVal *pcv    共通変数へのポインタ
  227.  *        ScrlVal *pvalh    横スクロールバーの値を格納するポインタ
  228.  *        ScrlVal *pvalv    縦スクロールバーの        〃
  229.  */
  230. void calcScrollBar(ComVal *pcv, ScrlVal *pvalh, ScrlVal *pvalv)
  231. {
  232.  
  233.     int edit, viewline, off, offv, offh;
  234.     Rect view, dest;
  235.  
  236.     view = pcv->windowPtr->graph.rect; /* ビューレクタングル    */
  237.     view.d.right -= SCRLBR_H;
  238.     view.d.bottom -= SCRLBR_H;
  239.  
  240.     dest.l.l_t = view.l.l_t;    /* ディスティネーションレクタングル */
  241.     dest.d.right = dest.d.left + pcv->logWidth;
  242.     dest.d.bottom = view.d.bottom;
  243.  
  244.     offh = view.d.left - pcv->dispX; /* 表示開始位置までの補正座標    */
  245.     offv = view.d.top - pcv->dispY;
  246.  
  247.     /* 縦方向のスクロール */
  248.     edit = pcv->logHeight;        /* 全体の行数            */
  249.     /* テキスト先頭から表示の最下位行までの行数 */
  250.     off = view.d.bottom - offv;
  251.     edit = (edit < off) ? off : edit; /* 全体行数を補正する        */
  252.     pvalv->dMax = edit;        /* コントロール定義関数のデータ    */
  253.     viewline = view.d.bottom - view.d.top;
  254.     pvalv->max = edit - viewline;    /* 最大値を計算する        */
  255.     pvalv->val = view.d.top - offv;    /* 現在値を計算する        */
  256.  
  257.     /* 横方向のスクロール */
  258.     edit = dest.d.right - dest.d.left;
  259.     off = view.d.right - offh;
  260.     edit = (edit < off) ? off : edit; /* 全体桁数を補正する        */
  261.     pvalh->dMax = edit;        /* コントロール定義関数のデータ */
  262.     viewline = view.d.right - dest.d.left;
  263.     pvalh->max = edit - viewline;    /* 最大値を計算する        */
  264.     pvalh->val = dest.d.left - offh; /* 現在値を計算する        */
  265. }
  266.  
  267. /******************************************************************************
  268.  *    resizeScrollBar():    ウィンドウとスクロールバーのサイズ変更
  269.  ******************************************************************************
  270.  *    引数:    ComVal *pcv    共通変数へのポインタ
  271.  */
  272. void resizeScrollBar(ComVal *pcv)
  273. {
  274.     Rect rcH, rcV;
  275.  
  276.     /* スクロールバーの位置と大きさを計算する */
  277.     rcH = rcV = pcv->windowPtr->graph.rect;
  278.     rcH.d.top = rcH.d.bottom - SCRLBR_H;
  279.     rcH.d.right -= SCRLBR_H;
  280.     rcV.d.left = rcV.d.right - SCRLBR_H;
  281.     rcV.d.bottom -= SCRLBR_H;
  282.  
  283.     CMHide(pcv->scrlBrHHdl);    /* スクロールバーを消去する    */
  284.     CMHide(pcv->scrlBrVHdl);
  285.  
  286.     CMMove(pcv->scrlBrHHdl, rcH.l.l_t);
  287.     CMSize(pcv->scrlBrHHdl, LONGWORD(rcH.d.right - rcH.d.left, SCRLBR_H));
  288.     CMMove(pcv->scrlBrVHdl, rcV.l.l_t);
  289.     CMSize(pcv->scrlBrVHdl, LONGWORD(SCRLBR_H, rcV.d.bottom - rcV.d.top));
  290.  
  291.     setScrollBar(pcv);
  292.  
  293.     CMShow(pcv->scrlBrHHdl);    /* スクロールバーを表示する    */
  294.     CMShow(pcv->scrlBrVHdl);
  295.     WMDrawGBox(pcv->windowPtr);    /* サイズボックスを描画する    */
  296. }
  297.